#include "mbed.h"
#include "max31865.h"
#include "pid.h"
//------------------------------------
// Hyperterminal configuration
// 9600 bauds, 8-bit data, no parity
//------------------------------------
PwmOut mypwm(PC_9);//PC_9
Serial pc(SERIAL_TX, SERIAL_RX);

DigitalOut mypin(PC_0);
DigitalOut mosfet_ctrl(PC_8);
//void write_type(unsigned char data);
//unsigned char read_data(unsigned char add);
//void write_data(unsigned char add,unsigned char data);

/**********************************************************************************************************************************************/

//PID算法温控C语言


#include "pid.h"
#include "max31865.h"
#include<math.h>
#include<string.h>
//Ticker tiker_pwm;
double compute_temp(unsigned int adc_code,unsigned int bottom,unsigned int top);

/**********************************************************************************************************************************************/



const unsigned int temp_adc_code[46]={
        1517,       2394,       3254,       4101,       4936,       5762,       6579,       6903,       7227,       7550,
//  -200        -175        -150        -125        -100        -75         -50         -40         -30         -20     
        7871,       8192,       8512,       8830,       9148,       9465,       9781,       10096,  10410,  10723,
//  -10         0               10          20          30          40          50          60          70          80
        11035,  11346,  11657,  11966,  12274,  12582,  12888,  13194,  13498,  13802,
//  90          100         110         120         130         140         150         160         170         180
        14104,  14406,  15156,  15901,  16639,  17371,  18098,  18818,  19533,  20242,
//  190         200         225         250         275         300         325         350         375         400
        20945,  21642,  22333,  23018,  23697,  24370
//  425         450         475         500         525         550
};

unsigned char bottom=0,top=46;
int order_to_temp(int order_number)  //ÐòºÅ×ª³ÉÎÂ¶È
{
        int t;
        switch(order_number)
        {
            case 0: t=-200;break;
            case 1: t=-175;break;
            case 2: t=-150;break;
            case 3: t=-125;break;
            case 4: t=-100;break;
            case 5: t=-75;break;
            case 6: t=-50;break;
            case 7: t=-40;break;
            case 8: t=-30;break;
            case 9: t=-20;break;
            case 10: t=-10;break;
            case 11: t=0;break;
            case 12: t=10;break;
            case 13: t=20;break;
            case 14: t=30;break;
            case 15: t=40;break;
            case 16: t=50;break;
            case 17: t=60;break;
            case 18: t=70;break;
            case 19: t=80;break;
            case 20: t=90;break;
            case 21: t=100;break;
            case 22: t=110;break;
            case 23: t=120;break;
            case 24: t=130;break;
            case 25: t=140;break;
            case 26: t=150;break;           
            case 27: t=160;break;
            case 28: t=170;break;
            case 29: t=180;break;
            case 30: t=190;break;           
            case 31: t=200;break;
            case 32: t=225;break;
            case 33: t=250;break;
            case 34: t=275;break;
            case 35: t=300;break;
            case 36: t=325;break;
            case 37: t=350;break;           
            case 38: t=375;break;
            case 39: t=400;break;
            case 40: t=425;break;
            case 41: t=450;break;               
            case 42: t=475;break;
            case 43: t=500;break;           
            case 44: t=525;break;
            case 45: t=550;break;           
        
        }
        return t;
}
    
double compute_temp(unsigned int adc_code,unsigned int bottom,unsigned int top)
{
    int t_top,t_bottom;
    double a,b,t_current_buf;
    if((top-bottom)/2==0)
    {
//      pc.printf("top= %d .\n\r", top);
//      pc.printf("bottom= %d .\n\r", bottom);
        t_top=order_to_temp(top);   //top ¶ÔÓ¦µÄÎÂ¶È
        t_bottom=order_to_temp(bottom); //bottom ¶ÔÓ¦µÄÎÂ¶È
        a=(t_top-t_bottom)/(double)(temp_adc_code[top]-temp_adc_code[bottom]); //a=(t1-t2)/(x1-x2)
//      pc.printf("a= %f .\n\r", a);
        b=t_top-a*temp_adc_code[top];
//      pc.printf("b= %f .\n\r", b);
        t_current_buf=a*adc_code+b;  //y=ax+b
        return t_current_buf;
    }
    else if(adc_code<=temp_adc_code[(top-bottom)/2+bottom])
    {
        t_current_buf=compute_temp(adc_code,bottom,(top-bottom)/2+bottom);
    }else if(adc_code>temp_adc_code[(top-bottom)/2+bottom])
    {
        t_current_buf=compute_temp(adc_code,(top-bottom)/2+bottom,top);
    }
    return t_current_buf;
}


unsigned int max31865_adc_code;
int t_pulsewidth=10,t_period=10,t_best_pulsewidth;
double t_current;

int temp_ctrl(double temp_set)
{
    max31865_adc_code=(max31865_read_data(1,0x01)<<7)+(max31865_read_data(1,0x02)>>1);
    t_current=compute_temp((max31865_read_data(1,0x01)<<7)+(max31865_read_data(1,0x02)>>1),0,46);
  //  pc.printf("current temp %f .  ", (((double)max31865_adc_code)/32-256));
  //  pc.printf("set temp %f .", temp_set);//\n\r
    if(temp_set-10>=0&&t_current<temp_set-10)
    {
        t_pulsewidth=t_period;
        mypwm.pulsewidth_ms(t_pulsewidth);
        wait_ms(10);
    //    pc.printf("t1 .");
    }
    if(temp_set-10>=0&&t_current>temp_set-10&&t_current<temp_set)
    {
        if(t_pulsewidth+1<=t_period)
            t_pulsewidth+=1;
        mypwm.pulsewidth_ms(t_pulsewidth);
        wait_ms(100);
    //    pc.printf("t2.");
    }
    
    if(temp_set+10<=t_period&&t_current>temp_set+10)
    {
        t_pulsewidth=0;
        mypwm.pulsewidth_ms(t_pulsewidth);
        wait_ms(10);
    //    pc.printf("t3 .");
    }
    if(temp_set+10<=t_period&&t_current<temp_set+10&&t_current>temp_set)
    {
        if(t_pulsewidth-1>=0)
            t_pulsewidth-=1;
        mypwm.pulsewidth_ms(t_pulsewidth);
        wait_ms(100);
  //      pc.printf("t4 .");
    }

}
//int main() 
//{
//    unsigned char temp_set,pulse_buf;
//  int i = 1;
//    unsigned int temp_buf,temp_adc_code;
//    
//  pc.printf("Hello World !\n\r");
//  max31865_init();
//    max31865_write_data(1,0x80,0xd1);         //Auto Mode, 3-Wire, 50Hz
//    max31865_write_data(2,0x80,0xd1);         //Auto Mode, 3-Wire, 50Hz
//	  max31865_write_data(3,0x80,0xd1);         //Auto Mode, 3-Wire, 50Hz
//    wait_ms(70);

//	mypwm.period_us(100);
//  mypwm.pulsewidth_us(50);
//    temp_set=200;
//	void PIDBEGIN();
//  while(1) 
//  { 



//		pulse_buf=compare_temper(1);
//			mypwm.pulsewidth_us(pulse_buf);

//  }
//}
struct _pid{
float SetSpeed;//定义设定值
float ActualSpeed;//定义实际值
float err;
//定义偏差值
float err_last;//定义上一个偏差值
float Kp,Ki,Kd;//定义比例、积分、微分系数
float voltage;//定义电压值（控制执行器的变量）
float integral;//定义积分值
}pid;

void PID_init(){
	printf("PID_initbegin\n");
	pid.SetSpeed=0.0;
	pid.ActualSpeed=0.0;
	pid.err=0.0;
	pid.err_last=0.0;
	pid.voltage=0.0;
	pid.integral=0.0;
	pid.Kp=0.2;
	pid.Ki=0.015;
	pid.Kd=0.2;
	printf("PID_initend\n");
}

float PID_realize(float temp)
{
	pid.SetSpeed=temp;

	pid.err=pid.SetSpeed-pid.ActualSpeed;
	pid.integral+=pid.err;
	pid.voltage=pid.Kp*pid.err+pid.Ki*pid.integral+pid.Kd*(pid.err-pid.err_last);
	pid.err_last=pid.err;
	pid.ActualSpeed=pid.voltage*1.0;
	return pid.ActualSpeed;
}
int main(){
	
	  max31865_init();
    max31865_write_data(1,0x80,0xd1);         //Auto Mode, 3-Wire, 50Hz
    max31865_write_data(2,0x80,0xd1);         //Auto Mode, 3-Wire, 50Hz
	  max31865_write_data(3,0x80,0xd1);         //Auto Mode, 3-Wire, 50Hz
    wait_ms(70);

	mypwm.period_us(100);
  mypwm.pulsewidth_us(50);
	
	printf("Systembegin\n");
	PID_init();
	int count=0;
	while(1)
	{
  max31865_adc_code=(max31865_read_data(1,0x01)<<7)+(max31865_read_data(1,0x02)>>1);
  t_current=compute_temp((max31865_read_data(1,0x01)<<7)+(max31865_read_data(1,0x02)>>1),0,46);
	pc.printf("current_temp1 %f .\n\r", t_current);
	pc.printf("current_temp2 %f .\n\r", ((double)(((max31865_read_data(2,0x01)<<7)+(max31865_read_data(2,0x02)>>1)))/32-256));
	pc.printf("current_temp3 %f .\n\r", ((double)(((max31865_read_data(3,0x01)<<7)+(max31865_read_data(3,0x02)>>1)))/32-256));

	pid.ActualSpeed=t_current;	
	float	speed=PID_realize(100.0);

	printf("%f\n",speed);
	//count++;
	}
	return 0;
}
 